package Util;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class Rsa2Test {
    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuV5EeYE0YFiwFHsgr50GQOKXWemslfEfv/ys0Iw1tfEhGhW/4PvW+I1+rclp4hF1mIV6x18k2yOmb8pEaQ9h3zKNQb29TiiFWWChvXISZnHpBirn25kOD8bqMu9iPEIYvM5jtvaUThO5zOxB4IdWmLXKSSAZqvWbnPAXXSJOreAsaOjTLR0m4M1wnKsOu8wkQ8n/Ji2SHPqOTm8zWam6gMA+20VHLQm2JVLplzSWAc20N2jUMWaMNRg8Nt826qj4EVSN4l8jV+RVoqUzFIBg6aOsAxd4Tk9WdMUXbQXxJHU+lMq7kShm21og3fa6Gu+VuJpZrzNMu4O2YblZKGiZ+wIDAQAB";
        String privateKeyBase64 = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5XkR5gTRgWLAUeyCvnQZA4pdZ6ayV8R+//KzQjDW18SEaFb/g+9b4jX6tyWniEXWYhXrHXyTbI6ZvykRpD2HfMo1Bvb1OKIVZYKG9chJmcekGKufbmQ4Pxuoy72I8Qhi8zmO29pROE7nM7EHgh1aYtcpJIBmq9Zuc8BddIk6t4Cxo6NMtHSbgzXCcqw67zCRDyf8mLZIc+o5ObzNZqbqAwD7bRUctCbYlUumXNJYBzbQ3aNQxZow1GDw23zbqqPgRVI3iXyNX5FWipTMUgGDpo6wDF3hOT1Z0xRdtBfEkdT6UyruRKGbbWiDd9roa75W4mlmvM0y7g7ZhuVkoaJn7AgMBAAECggEAFGeKBg3w5AIfL8H18R7Jx26p1l3gf4jRQ+Leav5kEyj9yc9HFc7i9O0uWpbnLtlZJnba8wNIHU8pTPjo2t+0mEsKPYhTRD01oIcAhsf9uoUjb2hdqVCJubbdpMmw+I0WCAJ3+3XdEVMeiq4e+kYrhBfOson0CVuLy5SqHbhfDMiF6SzRiTFMAELos7SwfjXZ0VAclGP7do/XWyUp2b2l9Z0nnaeKU2ecNBZlDXKcpsZ2Omz8HIXyJpeKooN63DSkjobPm6+/saNAL5118ZC8SxnvbZ61gsEk8/feHoYr58g6zgllLEb5uR7DJjmxrCF/bMqGv2OQ35s0cnPwUds/cQKBgQD7JACTjg2D/mvBSeZxsmOiLqJIoxeUOlH7OliPe6uF9XAJat2LJCpN5UPbUqgBC280SvzhJG103WeZIBNYiRqxC0qQUw1qUkpavJ1TkYw7lO5m/9b5TebQ05qTiBWd1DmJYbXfPQRjwjAG2/MkGIvdnZ43NhqnQeNXUHtr7T1RrQKBgQC89HgDymVmgHo1Ffc1z1cMOdnJzIXr6O3Gtj5Zhra+98qqKT/HAIAIhKsn9zNLUGT+XbkB1J5K68A1JlXc1LEZIiq0TEXAEerTH3XlplhdZ8qvRnVm48hqwyIQ+ZTllzOYloH5cHQkBsPkCIN7rz0N+P2SC7cw5Uo1Rr3vS+8fRwKBgC8lSBJrNXBU/8eOZvtrILceiAqYy2FhPWirQFrXPZDtTXYHIMXxKRvscTuoHa/shJjNhwGBBCdPNRaS5e7V9jPMSdgkLz2JaznzdJlulmPNBqBBYQr2K+GCB9+wSVaSs6ZtuGXLH5rWpotzGQbqsL8OytfUiVZi0RngGvtc0wkVAoGADb5+iFANhiIsQXZCkBBv1XzTwaD10M4VlZGmAV8SJdviSvRLJk98AKKdzH9npL/JSNNKZL6xcOOrDHKoZjK2WwyoLIsru6fR+99a9QRfgxPMo2ktmvlQl6tv6+orkXOpFh1EgP9UA1bWotyXq8R4XW7SCvB9N7pF5pApuqE8WHsCgYEAvKir/VM1K9Qhk78EshIXygL9F8LQxhpRkquZ3w/81fchn+/xLJv6HHpGLaGywAPM/kONcDkvJFLmHJDQ2cwLgrX2x0bUFRxNjQ0RLT7zjIuJq/WxECLVh6xDI8yGqT6OU0wfMEzinzm5eLaIwqRQLZoI0Qxvvn0nBjSh6/+iJD0=";

        PublicKey publicKey = getPublicKey(publicKeyBase64);
        PrivateKey privateKey = getPrivateKey(privateKeyBase64);

        // 原始数据
        byte[] originalData = "Hello, RSA!".getBytes();

        // 使用公钥进行加密
        byte[] encryptedData = encryptWithPublicKey(originalData, publicKey);

        // 使用私钥进行签名
        byte[] signature = signData(originalData, privateKey);

        // 使用公钥进行验签
        boolean isVerified = verifySignature(originalData, signature, publicKey);

        // 使用私钥进行解密
        byte[] decryptedData = decryptWithPrivateKey(encryptedData, privateKey);

        System.out.println("Original Data: " + new String(originalData));
        System.out.println("Encrypted Data: " + Base64.getEncoder().encodeToString(encryptedData));
        System.out.println("Signature: " + Base64.getEncoder().encodeToString(signature));
        System.out.println("Verification Result: " + isVerified);
        System.out.println("Decrypted Data: " + new String(decryptedData));
    }

    // 使用公钥加密数据
    public static byte[] encryptWithPublicKey(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    // 使用私钥进行签名
    public static byte[] signData(byte[] data, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data);
        return signature.sign();
    }

    // 使用公钥进行验签
    public static boolean verifySignature(byte[] data, byte[] signature, PublicKey publicKey) throws Exception {
        Signature verifySignature = Signature.getInstance("SHA256withRSA");
        verifySignature.initVerify(publicKey);
        verifySignature.update(data);
        return verifySignature.verify(signature);
    }

    // 使用私钥解密数据
    public static byte[] decryptWithPrivateKey(byte[] encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(encryptedData);
    }
    // 从Base64字符串获取公钥
    public static PublicKey getPublicKey(String publicKeyBase64) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }

    // 从Base64字符串获取私钥
    public static PrivateKey getPrivateKey(String privateKeyBase64) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyBase64);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }
}
